# -*- coding: utf-8 -*-
import math
from . import base_dispatch
from . import realtime_data
from . import realtime_model
from ..solver import lp_solve1

class realtime_dispatch(base_dispatch.base_dispatch):

    def __init__(self,micro_grid):
        super(realtime_dispatch, self).__init__()
        self.dispatch_id = None

        self.lp_solve = lp_solve1.lp_solve1()

        self.micro_grid = micro_grid

        self.realtime_data = realtime_data.realtime_data(micro_grid)

    # PV is the day ahead forecast of next day
    # load is the day ahead forecast of next day
    def dayschedule(self, pv, load, history_pv, history_load, price):
        # specifically for pv, battery
        self.realtime_data.update_load(load)

        self.realtime_data.update_pv(pv)

        self.realtime_data.update_price(price)

        # optimization model
        opt_model = realtime_model.realtime_model()

        opt_model.update_data(self.realtime_data)

        # solving
        schedule = self.lp_solve.run(opt_model.optimize_model())

        return schedule

    # realtime_load, realtime_pv is realtime value every five minutes
    def run(self, day_schedule, realtime_load, realtime_pv, forecast_load, forecast_pv):
        # consider all services battery can provide in short time
        # Step 1: forecast all services needed in short time

        # Step 2: formulize realtime dispatch model
        # day_schedule > 0 dichage day_schedule < 0 chage
        battery_p = self.micro_grid.get_battery_outpower_bound()
        #battery_soc = self.micro_grid.get_battery_soc()

        if day_schedule > 0:# and (realtime_load > realtime_pv):
            delta_net_load = (realtime_load - realtime_pv) - (forecast_load - forecast_pv)
            if delta_net_load > 0:
               dispatch_value = min(day_schedule + delta_net_load, battery_p)#, battery_soc)
            elif delta_net_load < 0:
               dispatch_value = max(day_schedule + delta_net_load, 0)
            else:
               dispatch_value = day_schedule

        elif day_schedule < 0:
            dispatch_value = day_schedule
        else:
            dispatch_value = 0


        #round dispatch value to integer
        if dispatch_value > 0:
           dispatch_value = math.floor(dispatch_value)
        else:
           dispatch_value = math.ceil(dispatch_value)

        control_command = []
        for i in range(0, len(self.micro_grid.device_list)):
            if self.micro_grid.device_list[i].dev_id == 2:
               device_command = dict()
               device_command['device_id'] = "2"
               device_command['p_value'] = dispatch_value
               device_command['q_value'] = None
               device_command['type'] = "Realtime"

               control_command.append(device_command)

        commands = {"10401":control_command}
        #control_command_str = json.dumps(control_command)

        return commands
